/*
 * launcher.cpp
 *
 *  Created on: Oct 29, 2013
 *      Author: m
 */

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include "CPrinter.h"
#include "NewSharedMemory.h"
#include "NewSemaphore.h"
#include "Sequence.h"
#include "DefinicionesComunes.h"

#define PROCESO_PATH "./proceso"

using namespace ipc;

int main( int argc, char* argv[] )
{
    char *args[3];
    int nProcesos;
    std::stringstream ss;

    // Inicializo el CPrinter
    CPrinter::setHeader( "launcher");

    // Parseo argumentos
    // argv[1] : Cantidad de procesos en la barrera
    if ( argc != 2 )
    {
        CPrinter::printErr( "Argumentos Invalidos.\n"
                "USO:\t\t proceso [cantidad total procesos]." );
        exit( 1 );
    }
    else
    {
        ss << argv[1];
        ss >> nProcesos;
    }

    // Creo los IPCs
    SharedMemory<int>::create( BASE_FILE, SHM_CONTADOR, 1 ).initialize( 0 );
    SharedMemory<int>::create( BASE_FILE, SHM_DATOS, nProcesos ).initialize( 0 );
    Semaphore::create( BASE_FILE, SEM_PROCESO, nProcesos ).initialize( 0 );
    Semaphore::create( BASE_FILE, MUTEX_CONTADOR, 1 ).initialize( 1 );
    Sequence::create( BASE_FILE, SEQ_ID );

    // Lanzo los procesos
    args[0] = (char*) PROCESO_PATH;
    args[1] = argv[1];
    args[2] = NULL;

    for ( int i = 0; i < nProcesos; i++ )
    {
        pid_t pid = fork();

        if( pid < 0 )
        {
            CPrinter::printErr( "Error al iniciar el proceso %d", i );
            exit(1);
        }
        else
        {
            if(!pid)
            {
                if( execve( PROCESO_PATH, args, NULL ) )
                {
                    CPrinter::printErr( "Error al cargar el proceso %d.\n", i );
                    exit(1);
                }
            }
        }
    }

    CPrinter::printOut( "done" );

    return 0;
}
